#ifndef ASIO_SERVER_SESSION_H
#define ASIO_SERVER_SESSION_H

#include <mutex>
#include <queue>
#include <memory>

#include <boost/asio.hpp>
#include <boost/uuid/uuid_io.hpp>
#include <boost/uuid/uuid_generators.hpp>

#include "MsgNode.h"

using namespace std;
using namespace boost::asio;
using boost::asio::ip::tcp;

class Server;

class Session : public enable_shared_from_this<Session> {
public:
    Session(io_context &ioc, Server *server);

    ~Session();

    tcp::socket &GetSocket();

    void Start();

    string GetUuid();

    void Send(const string &msg, short msg_id);

private:
    void HandleReadHead(const boost::system::error_code &ec, size_t bytes_transferred,
                        const shared_ptr<Session> &session);

    void HandleReadBody(const boost::system::error_code &ec, size_t bytes_transferred,
                        const shared_ptr<Session> &session);

    void HandleWrite(const boost::system::error_code &ec, const shared_ptr<Session> &session);

    void Close();

private:
    tcp::socket _socket;
    Server *_server;
    string _uuid;

    //收到的消息结构
    char _head_data[4];
    std::shared_ptr<RecvNode> _recv_msg_node;

    queue<shared_ptr<SendNode> > _send_queue;
    mutex _send_lock;
};

class LogicNode {
    friend class LogicSystem;

public:
    LogicNode(const shared_ptr<Session> &session, const shared_ptr<RecvNode> &recv_node);

private:
    shared_ptr<Session> _session;
    shared_ptr<RecvNode> _recv_node;
};

#endif //ASIO_SERVER_SESSION_H
